Python之路 - 包导入详解
介绍 🍀
为了帮助组织模块并提供命名层次结构 , Python有一个概念 : 包
包就相当于一个文件系统的目录 , 模块相当于目录中的文件 , 也就是说所有的包都是模块 , 但不是所有的模块都是包
包只是一种特殊的模块 , 具体来说 , 包含__path__
属性的任何模块都被视为包
所有模块都有一个名称 , 子包名与他们的父包名由点隔开 , 类似于Python的标准属性访问语法
Python定义了两种类型的包 , 即 regular packages 和 namespace packages , 我们通常使用的就是regular packages , 对于namespace packages可通过上述链接进行学习
常规包 🍀
常规包是传统的包 , 因为它们存在于Python 3.2 及更早的版本中 ; 常规包通常实现为包含__init__.py
文件的目录
当我们导入常规包时 , 这个__init__.py
文件会被隐式执行 (这意味着我们应该在__init__.py
文件中完成我们的导入 , 即初始化包) , 它定义的对象被绑定到包命名空间中 ; Python会在导入时为模块添加一些其他属性 , 如下 :
1 | parent/ |
在我们使用import
导入文件时 , 产生命名空间的名字来源于文件 , import packages
产生的命名空间的名字同样来源于文件 , 即包下的__init__.py
, 导入包本质就是在导入该文件
注意 : 在Python 3中 , 即使包下没有__init__.py
文件 , import packages
仍然不会报错 , 而在Python 2中 , 包下一定要有该文件 , 否则import packages
就会抛出异常
导入包 🍀
glance包
1 | glance/ |
import 🍀
1 | import glance.db.models |
from … import … 🍀
1 | # import后接的必须是明确的模块或者方法或者类或者变量,否则会抛出异常 |
绝对导入与相对导入 🍀
我们的glance包时写给别人用的 , 但是在glance包内部也会有彼此之间互相导入的需求 , 那么就有了绝对导入和相对导入两种方式 :
绝对导入 : 以glance
作为起始
相对导入 : 用.
或者..
的方式最为起始 , 只能在一个包中使用 , 即包内目录
我们在glance/api/version.py
中导入glance/cmd/manage.py
glance/api/version.py 下
1 | # 绝对导入 |
绝对导入
1 | glance/ |
相对导入
1 | glance/ |
单独导入 🍀
单独导入包时不会导入包中所有包含的所有子模块 , 如 :
1 | import glance |
上述导入会隐式执行__init__.py
, 所以我们可以让这个文件来初始化 , 如下 :
1 | # glance/__init__.py |